/**
 * Tasks:
 * 1. Для начала нужно нарисовать темно-серый фон на все окно
 * 2. Наненсти пунктирную логарифмическую сетку по дальности
 * 3. Нанести пунктирную линейнкую ( или логарифмическу?) сетку по глиссаде\курсу
 * 4. Добавить взлетно-посадочкую полосу черного цвета внизу экрана
 * 5. Добавить полосы отклонений по курсу(+-2 градуса) и по глиссаде(+-0.5 град)
 * 6. Добавить настройку масштаба по дальности( 20 км и 40 км)
 * 7. Настройки оторбражения по дальности( уровень нелинейности 0..10) 0 - линейно
 * 8. Добавить полосы для ухода на второй круг
 * 9. Отображать цель идущую на посадку в виде полоски + 2 предыдущих обзора
 * 10. Придумать формулу траектории для ВС идущего на посадку
 * 11. Добавить переключатель для отображения курса\глиссады
 * 12. Добавить перерисовку всех элементов при изменении размера окна
 * 13. Добавить кнопку полноэкранного режима.
 * 14. Добавить возможность включения записи изображения экрана( видео)
 * 15. Перерисовка всех линий после переключению направления посадки на ВПП
 */

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.ArrayList;

/**
 * Created with IntelliJ IDEA.
 * User: Val
 * Date: 09.06.13
 * Time: 20:20
 * To change this template use File | Settings | File Templates.
 */
public class IndicatorPosadki extends Application {

    public  double LRV = 0.25;  //Line Equal Height
    public double  kursParam = 0.1; // param to calculate kurs line
    private Group root;
    private VBox vBox;
    private Rectangle rectangle;
    private HBox hBox;
    private Color targetColor;
    private Label currentDistanceLabel;
    private Label infoLabel;
    private Label label;
    private int maxD = 20;
    private int linearIndex = 10;  //not used for now. Don't know how to use it.
    private int height = 700;
    private int width = 500;
    private int lineWidth = 700;
    private ArrayList<Path> distanceLines = new ArrayList<Path>();
    private ArrayList<Path> angleLines = new ArrayList<Path>();

    private boolean equalAngleOrDistance = true;

    private double kursCenterY = height * 0.75;
    private double kursBarHeight = height * 0.1;
    private double glissadaCenterY = height / 2 * 0.75;
    private double glissadaBarHeight = height * 0.2;
    private double glissadaDelta = 9.0;// +8 degree..-1 degree, or +3.5 deg..-1deg
    private double kursDelta = 10.0;// +15..-15 degrees on kurs indikator = has to be 30
    private Rectangle kursBar;
    private Rectangle glissadaBar;
    private Line glissadaLine;
    private Line kursLine;
    private Polygon poligonLRV;
    private Polygon poligonKursLine;
    private Polygon poligonKursLROPlus;
    private Polygon poligonKursLROMinus;
    private Polygon poligonGlissadaLine;
    private Polygon poligonGlissadaLROPlus;
    private Polygon poligonGlissadaLROMinus;

    private double firstKMLineOffsetPx = 200;
    private double zeroKMLineOffsetPx = width * Math.log10(0.45) / Math.log10(maxD) + firstKMLineOffsetPx;
    private Line dividerLine;
    private ToggleGroup group;
    private RadioButton radioEqualAngles;
    private RadioButton radioEqualDistance;
    private Double[] kursLineDoubleArray;
    private Double[] glissadaLinedoubleArray;
    private Timeline targetAnimation;
    private int timeInterval = 1200;
    //public int time = 0;
    private Arc arc;
    private Rectangle glissadaTarget;
    private Rectangle kursTarget;
    private int kursRadarOffset  = 50;
    private Stage stage;
    private Polygon poligonKorobochkaLine;
    private Double[] korobochkaDoubleArray;
    private int  landingDirection = 150;

    @Override
    public void start(Stage primaryStage) {
        makeBasicLayout(primaryStage);
        stage.setScene(new Scene(root));
        stage.show();
    }

    public void makeBasicLayout(Stage primaryStage) {
        primaryStage.setTitle("Indicator Posadki");
        stage = primaryStage;
        createRoot();




        //primaryStage.setScene(new Scene(root));
        //primaryStage.show();
    }

    public Group createRoot() {
        root = new Group();
        Line line2 = new Line(0, 0, 700, 700);
        line2.setStroke(Color.WHITE);
        vBox = new VBox(25);
        vBox.getChildren().addAll(line2);


        hBox = new HBox();
        hBox.getChildren().add(vBox);
        hBox.getChildren().add(addCheckBoxPanel());
        root.getChildren().add(hBox);
        addComponents();
        return root;
    }

    private void createTargetAnimation() {
        if (root.getChildren().contains(arc)) {
            root.getChildren().remove(arc);
        }
        if (targetAnimation != null) {
            targetAnimation.stop();
        }
        targetAnimation = new Timeline();

        glissadaTarget = new Rectangle(-100,-100,5,70);
        glissadaTarget.setArcHeight(15);
        glissadaTarget.setArcWidth(35);
        glissadaTarget.setFill(Color.YELLOW.darker());
        root.getChildren().add(glissadaTarget);

        kursTarget = new Rectangle(-100,-100,5,50);
        kursTarget.setArcHeight(15);
        kursTarget.setArcWidth(35);
        kursTarget.setFill(Color.YELLOW.darker());
        root.getChildren().add(kursTarget);



        targetAnimation.stop();
        targetAnimation.getKeyFrames().add(new KeyFrame(Duration.millis(timeInterval),
                new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent actionEvent) {
                            int pointsAmount = (int)(lineWidth - zeroKMLineOffsetPx);
                            //time++;
                            System.out.println("t: "+ IKO.sharedTime);
                            //System.out.println(time++ + " "+ glissadaLinedoubleArray[time * 2] + "-"+ glissadaLinedoubleArray[time * 2 + 1]);
                            int index = (5*Math.round(IKO.sharedTime/1000) + 1) % Nalet.points.length;
                            if((index<Nalet.points.length)&&(index>0)){
                                    if(Math.abs(Nalet.points[index]-330)<1){
                                        glissadaTarget.setX(distance2Pixel( Nalet.points[index-1]/1000));
                                        int ind = (pointsAmount *2  - (IKO.sharedTime )% Nalet.points.length * 2)  + 1;
                                        System.out.println("gliss id: " + ind);
                                        if(ind>0)
                                        glissadaTarget.setY(glissadaLinedoubleArray[ind]);

                                    }
                            }
                            //glissadaTarget.setX(glissadaLinedoubleArray[(pointsAmount - time) * 2] - 3);

                            //kursTarget.setX(kursLineDoubleArray[(pointsAmount - time) * 2] - 3);
                            //kursTarget.setY(kursLineDoubleArray[(pointsAmount - time) * 2 + 1] - 25);

                            //setting kurs
                            //int index = 5*Math.round(time * timeInterval/1000) + 1;
                            if((index<Nalet.points.length)&&(index>0)){
                                if(Math.abs(Nalet.points[index]-330)<13){
                                    if(Math.abs(Nalet.points[index]-330)>1){
                                         //330-Azimut
                                        System.out.println(" t: "+ IKO.sharedTime + " D: " + distance2Pixel( Nalet.points[index-1]/1000)
                                                + " kurs " + (330 - Nalet.points[index]));
                                        kursTarget.setX(distance2Pixel( Nalet.points[index-1]/1000));
                                        kursTarget.setY(kurs2Pixel(330 - Nalet.points[index]));

                                    }else{
                                        //atan2
                                        System.out.println(" t: "+ IKO.sharedTime + " D: " + distance2Pixel( Nalet.points[index-1]/1000 )
                                            + " kurs " + Math.atan2(kursRadarOffset, Nalet.points[index-1])/Math.PI*180);
                                        kursTarget.setX(distance2Pixel( Nalet.points[index-1]/1000));
                                        kursTarget.setY(kurs2Pixel(Math.atan2(kursRadarOffset, Nalet.points[index-1])/Math.PI*180));
                                    }
                                }
                            }
                    }
                }));
        targetAnimation.setCycleCount(Animation.INDEFINITE);
        targetAnimation.play();
    }

    private double kurs2Pixel(double kurs) {
        return  isDirectKurs()?
                0.71* height - kurs*height/60:
                0.71* height + kurs*height/60;
    }

    private void addComponents() {
        addBars();


        //createLRV(450);

        drawKorobochka();

        createKursLine(0);
        createKursLROPlus((int)(kursBarHeight / 2) );
        createKursLROMinus(-(int) (kursBarHeight / 2));

        createGlissadaLine(0);
        createGlissadaLROPlus(-(int)(kursBarHeight / 4) );
        createGlissadaLROMinus((int)(kursBarHeight / 4) );

        createDistanceLines();
        addDistanceLines();
        addAngleLines();
        createTargetAnimation();

    }

    private void redrawAllKursLines(){
        System.out.println("redraw korobochka");
        if(root.getChildren().contains(poligonKorobochkaLine)){
            root.getChildren().remove(poligonKorobochkaLine);
        }
        if(root.getChildren().contains(poligonKursLine)){
            root.getChildren().remove(poligonKursLine);
        }
        if(root.getChildren().contains(poligonKursLROPlus)){
            root.getChildren().remove(poligonKursLROPlus);
        }
        if(root.getChildren().contains(poligonKursLROMinus)){
            root.getChildren().remove(poligonKursLROMinus);
        }
        createKursLine(0);
        createKursLROPlus((int)(kursBarHeight / 2) );
        createKursLROMinus(-(int) (kursBarHeight / 2));
        drawKorobochka();
    }

    private void drawKorobochka() {
        System.out.println("drawKorobochka");
        poligonKorobochkaLine = new Polygon();
        int pontsAmount = Nalet.korobochka.length/2 ;
        korobochkaDoubleArray = new Double[pontsAmount * 2];
        for (int i = 0; i < pontsAmount; i++) {
            korobochkaDoubleArray[2 * i + 1] = kurs2Pixel( Nalet.korobochka[2 * i + 1]) + 29;
            korobochkaDoubleArray[2 * i] = distance2Pixel( Nalet.korobochka[2 * i]);
            System.out.println(" x:" + korobochkaDoubleArray[2 * i] + " y:" + korobochkaDoubleArray[2 * i + 1]);
        }
        poligonKorobochkaLine.getPoints().addAll(korobochkaDoubleArray);
        if(isDirectKurs()){
            poligonKorobochkaLine.getPoints().addAll(new Double[]{lineWidth + 0.0, height * 0.75});
            poligonKorobochkaLine.getPoints().addAll(new Double[]{lineWidth + 0.0,  height / 2.0});
        }else{
            poligonKorobochkaLine.getPoints().addAll(new Double[]{lineWidth + 0.0, height * 0.75});
            poligonKorobochkaLine.getPoints().addAll(new Double[]{lineWidth + 0.0,  height + 0.0});

        }
        poligonKorobochkaLine.setFill(null);
        poligonKorobochkaLine.setStroke(Color.YELLOW.darker());
        root.getChildren().add(poligonKorobochkaLine);

    }

    private void createGlissadaLine(int angleShift){
        //polygon for Optimal Glissada Line for Landing
        poligonGlissadaLine = new Polygon();
        int pontsAmount = (int)(lineWidth - zeroKMLineOffsetPx);
        glissadaLinedoubleArray = new Double[pontsAmount * 2+2];
        for (int i = 0; i <= pontsAmount; i++) {
            glissadaLinedoubleArray[2 * i + 1] = glissadaLRO2Pixel(i, angleShift);
            glissadaLinedoubleArray[2 * i] = i + zeroKMLineOffsetPx;
            System.out.println(" x:" + glissadaLinedoubleArray[2 * i] + " y:" + glissadaLinedoubleArray[2 * i + 1]);
        }
        poligonGlissadaLine.getPoints().addAll(glissadaLinedoubleArray);
        poligonGlissadaLine.getPoints().addAll(new Double[]{lineWidth + 0.0, height / 2.0});
        poligonGlissadaLine.getPoints().addAll(new Double[]{zeroKMLineOffsetPx / 2.0,  height / 2.0});
        poligonGlissadaLine.setFill(null);
        poligonGlissadaLine.setStroke(Color.GREEN);
        root.getChildren().add(poligonGlissadaLine);
    }

    private void createGlissadaLROPlus(int angleShift){
        //polygon for Optimal Glissada Line for Landing
        poligonGlissadaLROPlus = new Polygon();
        int pontsAmount = (int)(lineWidth - zeroKMLineOffsetPx);
        Double[] doubleArray = new Double[pontsAmount * 2+2];
        for (int i = 0; i <= pontsAmount; i++) {
            doubleArray[2 * i + 1] = glissadaLRO2Pixel(i, angleShift);
            doubleArray[2 * i] = i + zeroKMLineOffsetPx;
            System.out.println(" x:" + doubleArray[2 * i] + " y:" + doubleArray[2 * i + 1]);
        }
        poligonGlissadaLROPlus.getPoints().addAll(doubleArray);
        poligonGlissadaLROPlus.getPoints().addAll(new Double[]{lineWidth + 0.0, height / 2.0});
        poligonGlissadaLROPlus.getPoints().addAll(new Double[]{zeroKMLineOffsetPx/2.2, height / 2.0});
        poligonGlissadaLROPlus.setFill(null);
        poligonGlissadaLROPlus.setStroke(Color.BLUE);
        root.getChildren().add(poligonGlissadaLROPlus);
    }

    private void createGlissadaLROMinus(int angleShift){
        //polygon for Optimal Glissada Line for Landing
        poligonGlissadaLROMinus = new Polygon();
        int pontsAmount = (int)(lineWidth - zeroKMLineOffsetPx);
        Double[] doubleArray = new Double[pontsAmount * 2+2];
        for (int i = 0; i <= pontsAmount; i++) {
            doubleArray[2 * i + 1] = glissadaLRO2Pixel(i, angleShift);
            doubleArray[2 * i] = i + zeroKMLineOffsetPx;
            System.out.println(" x:" + doubleArray[2 * i] + " y:" + doubleArray[2 * i + 1]);
        }
        poligonGlissadaLROMinus.getPoints().addAll(doubleArray);
        poligonGlissadaLROMinus.getPoints().addAll(new Double[]{lineWidth + 0.0, height / 2.0});
        poligonGlissadaLROMinus.getPoints().addAll(new Double[]{zeroKMLineOffsetPx/1.8, height / 2.0});
        poligonGlissadaLROMinus.setFill(null);
        poligonGlissadaLROMinus.setStroke(Color.GREY);
        root.getChildren().add(poligonGlissadaLROMinus);
    }

    private void createKursLine(int angleShift){
        //polygon for Kurs Line for Landing
        poligonKursLine = new Polygon();
        int pontsAmount = (int)(lineWidth - zeroKMLineOffsetPx);
        kursLineDoubleArray = new Double[pontsAmount * 2+2];
        for (int i = 0; i <= pontsAmount; i++) {
            kursLineDoubleArray[2 * i + 1] = kursAngle2Pixel(i, angleShift);
            kursLineDoubleArray[2 * i] = i + zeroKMLineOffsetPx;
            System.out.println(" x:" + kursLineDoubleArray[2 * i] + " y:" + kursLineDoubleArray[2 * i + 1]);
        }
        poligonKursLine.getPoints().addAll(kursLineDoubleArray);
        if (isDirectKurs()){
            poligonKursLine.getPoints().addAll(new Double[]{lineWidth + 0.0, height / 2.0});
            poligonKursLine.getPoints().addAll(new Double[]{zeroKMLineOffsetPx/1.6, height / 2.0});
        }else{
            poligonKursLine.getPoints().addAll(new Double[]{lineWidth + 0.0, height + 0.0});
            poligonKursLine.getPoints().addAll(new Double[]{zeroKMLineOffsetPx/1.6, height + 0.0});
        }
        poligonKursLine.setFill(null);
        poligonKursLine.setStroke(Color.GREEN);
        root.getChildren().add(poligonKursLine);
    }

    private void createKursLROPlus(int angleShift){
        //polygon for Line Equal Height
        poligonKursLROPlus = new Polygon();
        int pontsAmount = (int)(lineWidth - zeroKMLineOffsetPx);
        Double[] doubleArray = new Double[pontsAmount * 2+2];
        for (int i = 0; i <= pontsAmount; i++) {
            doubleArray[2 * i + 1] = kursAngle2Pixel(i, angleShift);
            doubleArray[2 * i] = i + zeroKMLineOffsetPx;
            System.out.println(" x:" + doubleArray[2 * i] + " y:" + doubleArray[2 * i + 1]);
        }
        poligonKursLROPlus.getPoints().addAll(doubleArray);
        if (isDirectKurs()){
            poligonKursLROPlus.getPoints().addAll(new Double[]{lineWidth + 0.0, height / 2.0});
            poligonKursLROPlus.getPoints().addAll(new Double[]{zeroKMLineOffsetPx/1.7, height / 2.0});
        }else{
            poligonKursLROPlus.getPoints().addAll(new Double[]{lineWidth + 0.0, height +.0});
            poligonKursLROPlus.getPoints().addAll(new Double[]{zeroKMLineOffsetPx/1.7, height + 0.0});

        }

        poligonKursLROPlus.setFill(null);
        poligonKursLROPlus.setStroke(Color.GREY);
        root.getChildren().add(poligonKursLROPlus);
    }

    private void createKursLROMinus(int angleShift){
        //polygon for Line Equal Height
        poligonKursLROMinus = new Polygon();
        int pontsAmount = (int)(lineWidth - zeroKMLineOffsetPx);
        Double[] doubleArray = new Double[pontsAmount * 2+2];
        for (int i = 0; i <= pontsAmount; i++) {
            doubleArray[2 * i + 1] = kursAngle2Pixel(i, angleShift);
            doubleArray[2 * i] = i + zeroKMLineOffsetPx;
            System.out.println(" x:" + doubleArray[2 * i] + " y:" + doubleArray[2 * i + 1]);
        }
        poligonKursLROMinus.getPoints().addAll(doubleArray);
        if (isDirectKurs()){
            poligonKursLROMinus.getPoints().addAll(new Double[]{lineWidth + 0.0, height / 2.0});
            poligonKursLROMinus.getPoints().addAll(new Double[]{zeroKMLineOffsetPx/1.5, height / 2.0});
        }else{
            poligonKursLROMinus.getPoints().addAll(new Double[]{lineWidth + 0.0, height + 0.0});
            poligonKursLROMinus.getPoints().addAll(new Double[]{zeroKMLineOffsetPx/1.5, height + 0.0});


        }
        poligonKursLROMinus.setFill(null);
        poligonKursLROMinus.setStroke(Color.BLUE);
        root.getChildren().add(poligonKursLROMinus);
    }

    private void createLRV(int H) {
        //polygon for Line Equal Height
        poligonLRV = new Polygon();
        Double[] doubleArray = new Double[width * 2+2];
        for (int i = 0; i <= width; i++) {
            doubleArray[2 * i + 1] = glissadaAngle2Pixel(i);
            doubleArray[2 * i] = i + 200.0;
            System.out.println(" x:" + doubleArray[2 * i] + " y:" + doubleArray[2 * i + 1]);
        }
        poligonLRV.getPoints().addAll(doubleArray);
        poligonLRV.getPoints().addAll(new Double[]{lineWidth + 0.0,0.0});
        poligonLRV.setFill(null);
        poligonLRV.setStroke(Color.GREY);
        root.getChildren().add(poligonLRV);


    }

    private double glissadaD2A(int i) {
        return Math.toDegrees(Math.asin(LRV / pixel2Distance(i)));
    }
    //for LRV
    private double glissadaAngle2Pixel(int i){
        return height/2 - glissadaD2A(i) / glissadaDelta * height / 2;
    }
    //for glissada line and for glissada equal angle
    // i in pixels
    private double glissadaLRO2Pixel(int i, int shift){
        return glissadaCenterY - glissadaBarHeight /2  + kursD2A(i) / kursDelta * height / 8 + shift * popravka(i) ;
    }

    //linear decrease function
    private double popravka(int i) {

        return equalAngleOrDistance?1:(lineWidth - i +0.0) / lineWidth;
    }

    private double kursD2A(int i) {
        return Math.toDegrees(Math.asin(kursParam / pixel2Distance(i)));
    }

    private double kursAngle2Pixel(int i, int shift){
        return isDirectKurs()?
                kursCenterY - kursD2A(i) / kursDelta * height / 4 + shift * popravka(i):
                kursCenterY + kursD2A(i) / kursDelta * height / 4 + shift * popravka(i);
    }

    private double pixel2Distance(int i) {
        double distance =     Math.pow(10, (i+0.0)/ width * Math.log10(maxD));
        System.out.print(" d: "+ distance);
        return distance;
    }

    private void addBars() {
        rectangle = new Rectangle(0, 0, 350 * 2, 350 * 2);
        rectangle.setFill(Color.rgb(64, 64, 64));
        //root.getChildren().add(rectangle);

        glissadaBar = new Rectangle(0, glissadaCenterY - glissadaBarHeight / 2, 350 * 2, glissadaBarHeight);
        glissadaBar.setFill(Color.BLACK);
        //root.getChildren().add(glissadaBar);

        kursBar = new Rectangle(0, kursCenterY - kursBarHeight / 2, 350 * 2, kursBarHeight);
        kursBar.setFill(Color.BLACK);
        //root.getChildren().add(kursBar);

        dividerLine = new Line(0, height / 2, lineWidth, height / 2);
        dividerLine.setStroke(Color.BLACK);
        root.getChildren().addAll(dividerLine);

        glissadaLine = new Line(0, glissadaCenterY, lineWidth, glissadaCenterY);
        glissadaLine.setStroke(Color.WHITE);
        //root.getChildren().addAll(glissadaLine);

        kursLine = new Line(0, kursCenterY, lineWidth, kursCenterY);
        kursLine.setStroke(Color.WHITE);
        root.getChildren().addAll(kursLine);

    }

    private void removeBars(){
        root.getChildren().removeAll(rectangle, glissadaBar, kursBar, dividerLine, glissadaLine, kursLine);
    }

    private void addDistanceLines() {

        for (int i = 0; i <= (maxD==20?maxD:24); i++) {

            if (root.getChildren().contains(distanceLines.get(i))) {
                root.getChildren().remove(distanceLines.get(i));
            }
            root.getChildren().add(distanceLines.get(i));
        }
    }

    private void removeDistanceLines(){
        for (int i = 0; i < distanceLines.size(); i++) {

            if (root.getChildren().contains(distanceLines.get(i))) {
                root.getChildren().remove(distanceLines.get(i));
            }
        }
    }

    private void removeAngleLines(){
        for (int i = 0; i < angleLines.size(); i++) {

            if (root.getChildren().contains(angleLines.get(i))) {
                root.getChildren().remove(angleLines.get(i));
            }
        }
    }

    private void createDistanceLines() {
        distanceLines.clear();
        for (int i = 0; i <= maxD; i++) {
            //Line line = new Line(width * Math.log10(i) / Math.log10(maxD),0,width * Math.log10(i) / Math.log10(maxD) , height);
            //line.setStrokeDashOffset(1);
            //line.setStroke(Color.WHITE);
            Path path = PathBuilder.create().elements(
                    new MoveTo(distance2Pixel(i), 0),
                    new LineTo(distance2Pixel(i), height))
                    .build();
            path.setStroke(Color.GREY);
            path.setFill(Color.GREY);
            if (i % 5 != 0) {
                path.getStrokeDashArray().setAll(1d, 15d);
            }
            if((i>=20 && i%5==0)||(i<20)){
                distanceLines.add(path);
            }
            System.out.println((width * Math.log10(i == 0 ? 0.45 : i) / Math.log10(maxD) + 200) + "  -  " + i);
        }
    }

    private double distance2Pixel(double i) {
        return width * Math.log10(i == 0 ? 0.45 : i) / Math.log10(i == 0 ? 20 : maxD) + 200;
    }

    private void addAngleLines(){
        for(int i=0;i<10;i++){
            Path path = PathBuilder.create().elements(
                    new MoveTo(0, height * i / 18),
                    new LineTo(lineWidth, height * i / 18))
                    .build();
            path.setStroke(Color.GREY);
            path.setFill(Color.GREY);
            if(i==8){
                path.setStrokeWidth(2);
            }
            angleLines.add(path);

            if(i<9){
            //Angle labels
                Label label = new Label(" " + (9-i));
                label.setLayoutX(lineWidth - 50);
                label.setLayoutY(height * i / 18 - 10);

                root.getChildren().add(label);
            }

            root.getChildren().add(path);
        }

        for(int i=0;i<11;i++){
            Path path = PathBuilder.create().elements(
                    new MoveTo(0,          height/2 + height  * i / 20),
                    new LineTo(lineWidth,  height/2 + height  * i / 20))
                    .build();
            path.setStroke(Color.GREY);
            path.setFill(Color.GREY);
            if(i==5){
                path.setStrokeWidth(2);
            }
            angleLines.add(path);

            //Angle labels
            Label label = new Label(" " + (-(i - 5)*3) );
            label.setLayoutX(lineWidth - 50);
            label.setLayoutY(height/2 + height  * i / 20 - 10);
            root.getChildren().add(label);

            root.getChildren().add(path);
        }
    }


    private VBox addCheckBoxPanel() {
        VBox vbox = new VBox();
        vbox.setSpacing(10);
        final ComboBox<String> scaleComboBox = addScaleComboBox();
        final ComboBox<String> landingAzimutComboBox = addLandingDirectionComboBox();
        final CheckBox cb4 = new CheckBox("A30");
        cb4.setSelected(true);
        cb4.setTextFill(Color.LIGHTGREY);
        final ColorPicker colorPicker = new ColorPicker();
        colorPicker.setValue(Color.YELLOW);
        infoLabel = new Label("MAX DISTANCE ");
        infoLabel.setTextFill(Color.BLACK);
        label = new Label("Equal Lines For: ");
        label.setTextFill(Color.GREEN);
        colorPicker.setOnAction(new EventHandler() {
            @Override
            public void handle(Event arg0) {
                targetColor = colorPicker.getValue();
            }
        });
        currentDistanceLabel = new Label("D: ");

        group = new ToggleGroup();
        radioEqualAngles = new RadioButton("Equal Angle");
        radioEqualDistance = new RadioButton("Equal Distance");
        radioEqualAngles.setToggleGroup(group);
        radioEqualAngles.setSelected(true);
        radioEqualDistance.setToggleGroup(group);
        group.selectedToggleProperty().addListener(new ChangeListener<Toggle>(){
            public void changed(ObservableValue<? extends Toggle> ov,
                                Toggle old_toggle, Toggle new_toggle) {
                if (group.getSelectedToggle() != null) {
                    System.out.println(radioEqualAngles.isSelected());
                    equalAngleOrDistance = radioEqualAngles.isSelected();
                    clearRoot();
                    addComponents();
                }
            }
        });

        vbox.getChildren().addAll(infoLabel, scaleComboBox, label,  radioEqualAngles, radioEqualDistance, landingAzimutComboBox);

        return vbox;
    }

    private ComboBox<String> addLandingDirectionComboBox() {
        final ComboBox<String> landingDirectionComboBox = new ComboBox<String>();
        landingDirectionComboBox.getItems().addAll(
                "150",
                "330"
        );
        landingDirectionComboBox.setValue("150");
        landingDirectionComboBox.valueProperty().addListener(new ChangeListener<String>() {

            @Override
            public void changed(ObservableValue<? extends String> arg0,
                                String arg1, String arg2) {
                // TODO Auto-generated method stub
                landingDirection = Integer.parseInt(arg2);
                System.out.println("landing azimut: " + landingDirection);
                redrawAllKursLines();

            }

        });
        return landingDirectionComboBox;
    }

    private boolean isDirectKurs(){
        return landingDirection==150;
    }

    private ComboBox<String> addScaleComboBox() {
        final ComboBox<String> scaleCB = new ComboBox<String>();
        scaleCB.getItems().addAll("20", "40");
        scaleCB.setValue("20");
        scaleCB.valueProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> arg0,
                                String arg1, String arg2) {
                maxD = Integer.parseInt(arg2);
                System.out.println("maxD :" + maxD);
                clearRoot();
                addComponents();
            }
        });
        return scaleCB;
    }



    public static void main(String[] args) {
        launch(args);
    }

    private void clearRoot() {

        removeBars();
        removeDistanceLines();
        removeAngleLines();
        root.getChildren().removeAll(poligonLRV, poligonKursLine, poligonKursLROMinus,
                poligonKursLROPlus, poligonGlissadaLine, poligonGlissadaLROMinus,
                poligonGlissadaLROPlus);

    }
}
